#ifndef COMMAND
#define COMMAND

#include <network/streamingConnection.h>

#include <network\protocol.h>
#include <commands\commandFactory.h>

#include <string>
#include <vector>
#include <sstream>

using std::string;
using std::vector;
using std::stringstream;

#define REGISTER_COMMAND(ID, classname) \
  namespace { \
    commandFactory &cf = commandFactory::instance(); \
    bool foo = cf.registerCommand(ID, classname::create); \
  }

#define COMMAND_HEADER(classname) \
 classname : public command { \
    classname(); \
    classname(unsigned int _type_id, streamingConnection *_connection); \
  public: \
    static command *create(unsigned int cmd_id, streamingConnection *_connection = NULL) { \
      return new classname(cmd_id, _connection); \
    } \
    virtual void decode(stringstream &byte_stream, int size); \
    virtual void execute(); 

// Command interface
class command {

  unsigned int type_id;
  streamingConnection *connection;

private:

    void tokenizeHeader(const string& str, vector<string>& tokens, const string& delimiter = " ");

protected:

  vector<string> header_tokens;

  void sendBytes(const void *buffer, unsigned int count);

public:

  command() : type_id(0), connection(NULL) {
  }

  command(unsigned int _type_id, streamingConnection *_connection) : type_id(_type_id), connection(_connection) {
  }

  unsigned int getTypeId();
  streamingConnection *getconnection();

  virtual void decode(stringstream &byte_stream, int size);
  virtual void execute()=0;
};

#endif